﻿/**
 * @file deque_ie1.c
 * Copyright (c) 2021 Gaaagaa. All rights reserved.
 * 
 * @author  : Gaaagaa
 * @date    : 2021-06-02
 * @version : 1.0.0.0
 * @brief   : 对 双端队列 容器的数据进行 插入/删除 操作。
 */

/**
 * The MIT License (MIT)
 * Copyright (c) Gaaagaa. All rights reserved.
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "std_deque.h"
#include "std_mdebug.h"
#include <stdio.h>

////////////////////////////////////////////////////////////////////////////////

/**********************************************************/
/**
 * @brief 打印输出 xstd_deque_t 对象的各个节点元素。
 */
xstd_void_t printf_deque_int32(xdeq_this_t xdeq_this)
{
    xstd_size_t xst_count = 0;
    xdeq_iter_t xdeq_iter = std_deque_begin(xdeq_this);
    xdeq_iter_t xdeq_vend = std_deque_end(xdeq_this);

    if (std_deque_size(xdeq_this) <= 0)
    {
        printf("deque(0) \n");
        return;
    }

    printf("deque(%d) [[[\n", (xstd_int32_t)std_deque_size(xdeq_this));

    for (xst_count  = 0;
         xdeq_iter != xdeq_vend;
         xdeq_iter  = std_deque_next(xdeq_this, xdeq_iter))
    {
        printf("[%3d]=(%3d)",
            (xstd_int32_t)xst_count, std_deque_elem_int32(xdeq_this, xdeq_iter));

        if (++xst_count < std_deque_size(xdeq_this))
        {
            if (0 == (xst_count & 7))
                printf("\n");
            else
                printf(" , ");
        }
        else
        {
            printf("\n]]] deque\n\n");
        }
    }
}

////////////////////////////////////////////////////////////////////////////////

int main(int argc, char * argv[])
{
    xmdb_this_t xmdb_comm = XSTD_NULL;
    xstd_int32_t  xit_value = 0;
    xstd_int32_t  xit_count = 128;
    xdeq_this_t xdeq_this = XSTD_NULL;

    //======================================

    xmdb_comm = (xmdb_this_t)std_mdbcomm_start();

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    xdeq_this = std_deque_create_int32();

    printf("%d. mem count : %d, sizeof(xstd_deque_t) = %d\n",
           __LINE__,
           (xstd_int32_t)std_mdbcomm_count(),
           (xstd_int32_t)std_deque_sizeof());

    //======================================
    // assign

    printf("ASSIGN [ %d => [%d, %d) ]: ", 1, 0, xit_count);

    std_deque_assign_int32(xdeq_this, xit_count, 1);
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================
    // insert

    printf("INSERT N [ %d => [%d, %d) ]: ",
        2, xit_count / 2, xit_count / 2 + xit_count / 8);

    std_deque_insert_n_int32(
        xdeq_this, std_deque_iter(xdeq_this, xit_count / 2), xit_count / 8, 2);
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================
    // insert

    printf("INSERT BEGIN [ %d => [%d, %d) ]: ", 3, 0, 1);

    std_deque_insert_int32(
        xdeq_this, std_deque_begin(xdeq_this), 3);
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================
    // insert

    printf("INSERT END [ %d => [%d, %d) ]: ",
        4,
        (xstd_int32_t)std_deque_size(xdeq_this),
        (xstd_int32_t)std_deque_size(xdeq_this) + 1);

    std_deque_insert_int32(
        xdeq_this, std_deque_end(xdeq_this), 4);
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================
    // insert

    printf("INSERT AT [ %d => [%d, %d) ]: ", 5, 15, 16);

    std_deque_insert_int32(
        xdeq_this, std_deque_iter(xdeq_this, 15), 5);
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================
    // fill

    printf("FILL [ %d => [%d, %d) ]: ", 6, 0, xit_count / 8);

    std_deque_fill_int32(
        xdeq_this,
        std_deque_iter(xdeq_this, 0),
        std_deque_iter(xdeq_this, xit_count / 8),
        6);
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================
    // erase

    printf("ERASE BEGIN [ %d ]: ", 0);

    std_deque_erase(xdeq_this, std_deque_begin(xdeq_this));
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================
    // erase

    printf("ERASE RBEGIN [ %d ]: ", (xstd_int32_t)std_deque_size(xdeq_this) - 1);

    std_deque_erase(xdeq_this, std_deque_rbegin(xdeq_this));
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================
    // erase

    printf("ERASE RANGE [ %d, %d ]: ", 7, 41);

    std_deque_erase_range(
        xdeq_this,
        std_deque_iter(xdeq_this,  7),
        std_deque_iter(xdeq_this, 41));
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================
    // erase

    printf("ERASE RANGE [ %d, %d ]: ", 0, 12);

    std_deque_erase_range(
        xdeq_this,
        std_deque_begin(xdeq_this),
        std_deque_iter(xdeq_this, 12));
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================
    // erase

    printf("ERASE RANGE [ %d, %d ]: ",
        43, (xstd_int32_t)std_deque_size(xdeq_this) - 1);

    std_deque_erase_range(
        xdeq_this,
        std_deque_iter(xdeq_this, 43),
        std_deque_end(xdeq_this));
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================
    // clear

    printf("CLEAR: ");

    std_deque_clear(xdeq_this);
    printf_deque_int32(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    //======================================

    std_deque_destroy(xdeq_this);

    printf("%d. mem count : %d\n", __LINE__, (xstd_int32_t)std_mdbcomm_count());

    std_mdbcomm_stop();

    //======================================

    return 0;
}

/////////////////////////////////////////////////////////////////////////////////

